package com.loren.designer.service;

import com.loren.designer.data.dto.ScreenDto;
import com.loren.designer.data.form.QueryForm;
import com.loren.designer.data.form.ScreenForm;
import com.loren.designer.data.resp.MPage;
import com.loren.designer.exception.BusinessException;
import com.loren.designer.persistent.entity.Screen;
import com.loren.designer.persistent.mapper.ScreenMapper;
import com.loren.designer.utils.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
public class ScreenService {

    private final ScreenMapper screenMapper;

    @Transactional(readOnly = true)
    public MPage<ScreenDto> getScreenInfoList(QueryForm form) {
        IPage<Screen> pageInfo = new Page<>(form.getPage(), form.getSize());
        List<Screen> screenList = this.screenMapper.findByCondition(pageInfo, form);
        List<ScreenDto> dtoList = BeanUtils.sourceListToTargetList(screenList, ScreenDto.class);
        return MPage.pageInfo(pageInfo, dtoList);
    }

    @Transactional(readOnly = true)
    public ScreenDto getScreenInfo(String screenId) {
        Screen screen = this.screenMapper.selectById(screenId);
        if (screen == null) {
            return null;
        }
        return BeanUtils.sourceToTarget(screen, ScreenDto.class);
    }

    @Transactional
    public void saveScreenInfo(ScreenForm form) {
        Screen screen = BeanUtils.sourceToTarget(form, Screen.class);
        LambdaQueryWrapper<Screen> queryWrapper = Wrappers.<Screen>lambdaQuery()
                .select(Screen::getId, Screen::getEnable).eq(Screen::getId, form.getId());
        Screen diskScreen = this.screenMapper.selectOne(queryWrapper);
        if (diskScreen == null) {
            screen.setEnable(1);
            this.screenMapper.insert(screen);
        } else {
            screen.setEnable(diskScreen.getEnable());
            this.screenMapper.updateById(screen);
        }
    }

    @Transactional
    public void changeScreenStatus(String screenId) {
        Screen screen = this.getScreenInfoWithFields(screenId);
        LambdaUpdateWrapper<Screen> updateWrapper = Wrappers.<Screen>lambdaUpdate().eq(Screen::getId, screenId);
        this.screenMapper.update(Screen.builder().enable(screen.getEnable() ^ 1).build(), updateWrapper);
    }

    @Transactional
    public void deleteScreenInfo(String screenId) {
        Screen screen = this.getScreenInfoWithFields(screenId);
        this.screenMapper.deleteById(screen.getId());
    }

    private Screen getScreenInfoWithFields(String screenId) {
        LambdaQueryWrapper<Screen> queryWrapper = Wrappers.<Screen>lambdaQuery()
                .select(Screen::getId, Screen::getEnable).eq(Screen::getId, screenId);
        Screen screen = this.screenMapper.selectOne(queryWrapper);
        Optional.ofNullable(screen).orElseThrow(() -> new BusinessException("找不到大屏信息"));
        return screen;
    }
}
